/*
 * gen_sim_annealing.c
 *
 *  Created on: Sep 30, 2012
 *      Author: fredrik
 */


#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

//Parameters for the problem.
#define T_MAX 100
#define D_T 1
#define F_TARGET 100
#define N_NEIGHBORS 5 //The number of neighbors to be generated each itereation

//Problem specific defines go here


typedef struct{
	//Fill in attributes about state for the specific problem


}state_t;

state_t gen_init_state(void){
	state_t init_state;

	//Set up initial state here

	return init_state;
}

double obj_func(state_t state){
	//Fill inn the objective function for the specific problem
	double ret_val = 0;


	return ret_val;
}

void generate_neighbors(state_t state, state_t* neighbor_array){


}

void print_state(state_t state){


}


int main(int argc, char** argv){

	int i;

	int n_iterations = 0;

	srand(time(NULL));


	//The current sate
	state_t state = gen_init_state();

	//Array holding the neighbors of current state
	state_t neighbors[N_NEIGHBORS];

	double neighbors_obj_val[N_NEIGHBORS];

	state_t best_neighbor;
	double best_neighbor_val;

	//Variable that represents how close we are to the goal
	double q;

	//Probability of doing exploring instead of exploiting
	double p;

	//A random number generated to decide between exploring and exploiting
	double x;

	//The temperature or "jitter"
	double temp = T_MAX;

	//Current states objective value;
	double obj_value = obj_func(state);

	while(1){

		//Check if we have reached the goal
		if(obj_value >= F_TARGET || n_iterations > 1000){
			break;
		}

		generate_neighbors(state, neighbors);

		//Find the best neighbor
		best_neighbor_val = 0;
		for(i = 0; i < N_NEIGHBORS; i++){
			neighbors_obj_val[i] = obj_func(neighbors[i]);
			if(neighbors_obj_val[i] > best_neighbor_val){
				best_neighbor = neighbors[i];
			}
		}

		//Calculate q
		q = (best_neighbor_val - obj_value)/obj_value;

		//Calculate p
		p = exp(-q/temp);
		if(p > 1){
			p = 1;
		}

		//Make a random number between 0 and 1
		x = (double)rand()/RAND_MAX;

		//Decide between exploitation and exploration
		if(x > p){
			state = best_neighbor;
		}
		else{
			state = neighbors[rand() % N_NEIGHBORS];
		}

		//Decrease temperature
		temp -= D_T;

		n_iterations++;
	}

	//Print the solution

	printf("Solution found after %d iterations\n", n_iterations);
	print_state(state);

	return 0;
}
